package com.daoliuhe.scaffold.core;

import com.daoliuhe.scaffold.tools.Config;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.PasswordMatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.ldap.Control;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import java.util.Hashtable;

/**
 * ${DESCRIPTION}
 *
 * @author 21829
 * @create 2018-01-11 14:40
 **/
public class SimpleLDAPPasswordMatcher extends PasswordMatcher {

    private static final Logger logger = LoggerFactory.getLogger(SimpleLDAPPasswordMatcher.class);

    @Override
    public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
        logger.info("doCredentialsMatch");
        UsernamePasswordToken userToken = (UsernamePasswordToken) token;
        String userName = userToken.getUsername();
        String password = String.valueOf(userToken.getPassword());
        return authenticate(userName, password);
    }

    /**
     * LDAP校验是否验证成功
     *
     * @param userName 用户名
     * @param passWord 密码
     * @return 是否验证成功
     */
    private boolean authenticate(String userName, String passWord) {
        logger.info("authenticate , userName:{}", userName);
        boolean result = false;
        LdapContext ctx = null;
        Control[] connCtls = null;
        String userDN = "";
        Hashtable<String, String> env = new Hashtable<String, String>();
        try {
            if (StringUtils.isEmpty(passWord) || StringUtils.isEmpty(userName)) {
                result = false;
            } else {
                env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
                env.put(Context.PROVIDER_URL, Config.LDAP_URL);
                env.put(Context.SECURITY_PRINCIPAL, "daoliuhe\\" + userName);
                env.put(Context.SECURITY_CREDENTIALS, passWord);
                env.put(Context.SECURITY_AUTHENTICATION, "simple");

                ctx = new InitialLdapContext(env, connCtls);
                result = true;
            }
        } catch (AuthenticationException e) {
            result = false;
        } catch (NamingException e) {
            result = false;
        } finally {
            // 关闭LdapContext
            if (ctx != null) {
                try {
                    ctx.close();
                } catch (NamingException e) {
                    logger.error(e.toString());
                }
            }
        }
        logger.info("authenticate end , result:{}", result);
        return result;
    }
}
